import 'dart:convert';
import 'dart:ui';

import 'package:get/get.dart';
import 'package:library_base/entities/enum_entity.dart';
import 'package:shared_preferences/shared_preferences.dart';

class SPUtil {
  /// 内部构造方法，可避免外部暴露构造函数，进行实例化
  SPUtil._internal();

  ///主题
  static const String key_theme = 'key_theme';

  ///主题模式
  static const String key_mode = 'key_mode';

  ///token
  static const String key_token = 'key_token';

  ///刷新token
  static const String key_refreshToken = 'key_refreshToken';

  ///过期时间
  static const String key_expiresTime = 'key_expiresTime';

  ///用户id
  static const String key_userId = 'key_userId';

  ///编码前缀
  static const String key_barcodePrefix = 'key_barcodePrefix';

  ///初始值
  static const String key_initialValue = 'key_initialValue';

  ///用户名称
  static const String key_nickname = 'key_nickname';

  ///语言
  static const String key_locale = 'key_locale';

  ///单位是否为公斤
  static const String key_isKg = 'key_isKg';

  ///去皮重量
  static const String key_skinWeight = 'key_skinWeight';

  static const String key_latest_account = 'key_latest_account';
  static const String key_first_login = 'key_first_login';
  static const String key_old_version = 'key_old_version';

  static String get token => getString(key_token);

  static set token(String token) {
    putString(key_token, token);
  }

  static String get nickname => getString(key_nickname);

  static set nickname(String? nickname) {
    putString(key_nickname, nickname ?? '');
  }

  static String get barcodePrefix => getString(key_barcodePrefix);

  static set barcodePrefix(String token) {
    putString(key_barcodePrefix, token);
  }

  static int get expiresTime => getInt(key_expiresTime);

  static set expiresTime(int expiresTime) {
    putInt(key_expiresTime, expiresTime);
  }

  static int get initialValue => getInt(key_initialValue);

  static set initialValue(int initialValue) {
    putInt(key_initialValue, initialValue);
  }

  static set refreshToken(String refreshToken) {
    putString(key_refreshToken, refreshToken);
  }

  static String get refreshToken => getString(key_refreshToken);

  static set userId(int userId) {
    putInt(key_userId, userId);
  }

  static int get userId => getInt(key_userId);


  static set locale(String local) {
    putString(key_locale, local);
  }

  static String get locale{
    if(getString(key_locale, defValue:Language.system.name) == Language.system.name){
      return Language.system.name;
    }else if(getString(key_locale) == Language.english.name){
      return Language.english.name;
    }else{
      return Language.chinese.name;
    }
  }

  static Locale get language{
    if(locale == Language.system.name){
      if(Get.deviceLocale == null){
        return const Locale("zh", "CH");
      }else{
        if(Get.deviceLocale!.languageCode=="zh"){
          return const Locale("zh", "CH");
        }else{
          return const Locale("en", "US");
        }
      }
    }else if(getString(key_locale) == Language.english.name){
      return const Locale("zh", "CH");
    }else{
      return const Locale("zh", "CH");
    }
  }

  static set isJin(bool isKg) {
    putBool(key_isKg, isKg);
  }

  static bool get isJin => getBool(key_isKg);


  static set skinWeight(double skinWeight) {
    putDouble(key_skinWeight, skinWeight);
  }

  static double get skinWeight => getDouble(key_skinWeight);

  static SharedPreferences? _spf;

  static Future<SharedPreferences?> init() async {
    _spf ??= await SharedPreferences.getInstance();
    return _spf;
  }

  /// put object.
  static Future<bool>? putObject(String key, Object? value) {
    if (_spf == null) return null;
    return _spf!.setString(key, value == null ? "" : json.encode(value));
  }

  /// get obj.
  static T? getObj<T>(String key, T f(Map v), {T? defValue}) {
    Map? map = getObject(key);
    return map == null ? defValue : f(map);
  }

  /// get object.
  static Map? getObject(String key) {
    if (_spf == null) return null;
    String? _data = _spf!.getString(key);
    return (_data == null || _data.isEmpty) ? null : json.decode(_data);
  }

  /// get string.
  static String getString(String key, {String defValue = ''}) {
    if (_spf == null) return defValue;
    return _spf!.getString(key) ?? defValue;
  }

  /// put string.
  static Future<bool>? putString(String key, String value) {
    if (_spf == null) return null;
    return _spf!.setString(key, value);
  }

  /// get bool.
  static bool getBool(String key, {bool defValue = false}) {
    if (_spf == null) return defValue;
    return _spf!.getBool(key) ?? defValue;
  }

  /// put bool.
  static Future<bool>? putBool(String key, bool value) {
    if (_spf == null) return null;
    return _spf!.setBool(key, value);
  }

  /// get int.
  static int getInt(String key, {int defValue = 0}) {
    if (_spf == null) return defValue;
    return _spf!.getInt(key) ?? defValue;
  }

  /// put int.
  static Future<bool>? putInt(String key, int value) {
    if (_spf == null) return null;
    return _spf!.setInt(key, value);
  }

  /// get double.
  static double getDouble(String key, {double defValue = 0.0}) {
    if (_spf == null) return defValue;
    return _spf!.getDouble(key) ?? defValue;
  }

  /// put double.
  static Future<bool>? putDouble(String key, double value) {
    if (_spf == null) return null;
    return _spf!.setDouble(key, value);
  }

  /// get string list.
  static List<String> getStringList(String key, {List<String> defValue = const []}) {
    if (_spf == null) return defValue;
    return _spf!.getStringList(key) ?? defValue;
  }

  /// put string list.
  static Future<bool>? putStringList(String key, List<String> value) {
    if (_spf == null) return null;
    return _spf!.setStringList(key, value);
  }

  /// get dynamic.
  static dynamic getDynamic(String key, {Object? defValue}) {
    if (_spf == null) return defValue;
    return _spf!.get(key) ?? defValue;
  }

  /// have key.
  static bool? haveKey(String key) {
    if (_spf == null) return null;
    return _spf!.getKeys().contains(key);
  }

  /// get keys.
  static Set<String>? getKeys() {
    if (_spf == null) return null;
    return _spf!.getKeys();
  }

  /// remove.
  static Future<bool>? remove(String key) {
    if (_spf == null) return null;
    return _spf!.remove(key);
  }

  /// clear.
  static Future<bool>? clear() {
    if (_spf == null) return null;
    return _spf!.clear();
  }

  ///Sp is initialized.
  static bool isInitialized() {
    return _spf != null;
  }
}
